package cn.com.idmy.cloud.interceptor;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;

/**
 * 通用拦截器注册器
 * 提供类型安全的拦截器管理和执行功能
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class InterceptorRegistry {
    private final Map<Class<?>, List<Object>> interceptorMap = new ConcurrentHashMap<>();
    private final ApplicationContext ctx;

    /**
     * 手动注册拦截器
     */
    public <T> void register(@NotNull Class<T> interceptorClass, @NotNull T interceptor) {
        var interceptors = interceptorMap.computeIfAbsent(interceptorClass, k -> new CopyOnWriteArrayList<>());
        interceptors.add(interceptor);
        log.info("手动注册拦截器: {} -> {}", interceptorClass.getSimpleName(), interceptor.getClass().getName());
    }

    /**
     * 自动注册拦截器
     */
    public <T> void register(Class<T> interceptorClass) {
        var beans = ctx.getBeansOfType(interceptorClass);
        var interceptors = interceptorMap.computeIfAbsent(interceptorClass, k -> new CopyOnWriteArrayList<>());
        interceptors.addAll(beans.values());
        log.info("已注册 {} 个 {} 拦截器", interceptors.size(), interceptorClass.getSimpleName());
    }

    /**
     * 执行拦截器（无返回值）
     */
    public <T, P> void execute(@NotNull Class<T> interceptorClass, @NotNull P param, @NotNull BiConsumer<T, P> executor) {
        var interceptors = interceptorMap.get(interceptorClass);
        if (interceptors == null || interceptors.isEmpty()) {
            return;
        }
        for (var interceptor : interceptors) {
            try {
                @SuppressWarnings("unchecked")
                var typedInterceptor = (T) interceptor;
                executor.accept(typedInterceptor, param);
            } catch (Exception e) {
                log.error("执行拦截器异常: {}", interceptor.getClass().getName(), e);
                throw e;
            }
        }
    }

    /**
     * 执行拦截器（布尔返回值，任意一个返回false则停止）
     */
    public <T, P> boolean executeAsBoolean(@NotNull Class<T> interceptorClass, @NotNull P param, @NotNull BiFunction<T, P, Boolean> executor) {
        var interceptors = interceptorMap.get(interceptorClass);
        if (interceptors == null || interceptors.isEmpty()) {
            return true;
        }

        for (var interceptor : interceptors) {
            @SuppressWarnings("unchecked")
            T typedInterceptor = (T) interceptor;
            var result = executor.apply(typedInterceptor, param);
            if (Boolean.FALSE.equals(result)) {
                return false;
            }
        }
        return true;
    }
}